#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
#include <cv_bridge/cv_bridge.hpp>
#include <opencv2/opencv.hpp>
#include <regex>

using std::placeholders::_1;

class Listener : public rclcpp::Node
{
public:
    Listener() : Node("listener")
    {
        subscription_ = this->create_subscription<std_msgs::msg::String>(
            "hello_topic", 10, std::bind(&Listener::topic_callback, this, _1));
        
        // Create a window for displaying the image
        cv::namedWindow("ROS2 Message Display", cv::WINDOW_AUTOSIZE);
        
        // Create initial blank image
        create_blank_image("Waiting for message...");
        
        RCLCPP_INFO(this->get_logger(), "Listener node started");
    }

    ~Listener()
    {
        cv::destroyAllWindows();
    }

private:
    void topic_callback(const std_msgs::msg::String::SharedPtr msg)
    {
        RCLCPP_INFO(this->get_logger(), "Received: '%s'", msg->data.c_str());
        
        // Extract the number from the message using regex
        std::regex pattern("Hello, ROS2: (\\d+)");
        std::smatch matches;
        std::string number_str = "0";
        
        if (std::regex_search(msg->data, matches, pattern) && matches.size() > 1) {
            number_str = matches[1].str();
        }
        
        // Create and display image with the received number
        create_display_image(number_str, msg->data);
    }

    void create_blank_image(const std::string& text)
    {
        cv::Mat image(300, 600, CV_8UC3, cv::Scalar(50, 50, 50));
        
        // Put text in the center
        int baseline = 0;
        cv::Size text_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 1.0, 2, &baseline);
        cv::Point text_org((image.cols - text_size.width) / 2, (image.rows + text_size.height) / 2);
        
        cv::putText(image, text, text_org, cv::FONT_HERSHEY_SIMPLEX, 1.0, 
                   cv::Scalar(255, 255, 255), 2);
        
        cv::imshow("ROS2 Message Display", image);
        cv::waitKey(1);
    }

    void create_display_image(const std::string& number, const std::string& full_message)
    {
        // Create a colorful image
        cv::Mat image(400, 800, CV_8UC3, cv::Scalar(40, 40, 40));
        
        // Draw a background rectangle
        cv::rectangle(image, cv::Point(50, 50), cv::Point(750, 350), 
                     cv::Scalar(70, 130, 180), -1);
        cv::rectangle(image, cv::Point(50, 50), cv::Point(750, 350), 
                     cv::Scalar(255, 255, 255), 3);
        
        // Display the main number in large font
        cv::putText(image, number, cv::Point(400 - number.length() * 30, 200), 
                   cv::FONT_HERSHEY_DUPLEX, 3.0, cv::Scalar(255, 215, 0), 5);
        
        // Display the full message
        cv::putText(image, full_message, cv::Point(100, 300), 
                   cv::FONT_HERSHEY_SIMPLEX, 0.7, cv::Scalar(255, 255, 255), 2);
        
        // Display title
        cv::putText(image, "ROS2 Message Display", cv::Point(250, 30), 
                   cv::FONT_HERSHEY_SIMPLEX, 0.8, cv::Scalar(0, 255, 255), 2);
        
        cv::imshow("ROS2 Message Display", image);
        cv::waitKey(1);
    }

    rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscription_;
};

int main(int argc, char * argv[])
{
    rclcpp::init(argc, argv);
    auto node = std::make_shared<Listener>();
    rclcpp::spin(node);
    rclcpp::shutdown();
    return 0;
}